package com.xuzhiguang.lightnat.client.control.processor;

import com.xuzhiguang.lightnat.client.proxy.ProxyClient;
import com.xuzhiguang.lightnat.client.proxy.ProxyClientHolder;
import com.xuzhiguang.lightnat.client.transfer.TransferChannelPoolHolder;
import com.xuzhiguang.lightnat.common.manager.ProxyChannelManager;
import com.xuzhiguang.lightnat.common.manager.TransferChannelManager;
import com.xuzhiguang.lightnat.common.message.MessageProcessor;
import com.xuzhiguang.lightnat.common.message.NatMessage;
import com.xuzhiguang.lightnat.common.message.control.ConnectPush;
import com.xuzhiguang.lightnat.common.message.control.ConnectResponse;
import com.xuzhiguang.lightnat.common.message.transfer.ConnectRequest;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class ConnectPushProcessor implements MessageProcessor {

    @Override
    public void process(ChannelHandlerContext ctx, NatMessage natMessage) {

        log.debug("proxy ConnectPushProcessor. channel:{}", ctx.channel());

        if (natMessage.getBody() instanceof ConnectPush) {
            ConnectPush push = (ConnectPush) natMessage.getBody();

            // 连接后端服务器
            ProxyClient proxyClient = ProxyClientHolder.get();
            boolean connectResult = proxyClient.connect(push.getSessionId(), push.getSourceHost(), push.getSourcePort());

            ConnectResponse response = new ConnectResponse();
            response.setSuccess(false);
            response.setSessionId(push.getSessionId());
            if (connectResult) {

                // 获取空闲的 transfer channel
                Channel transferChannel = TransferChannelPoolHolder.get().getChannel(5000L);
                if (transferChannel != null) {
                    response.setSuccess(true);

                    // 绑定 sessionId 和 transferId
                    TransferChannelManager.setSessionId(transferChannel, push.getSessionId());
                    Channel proxyChannel = ProxyChannelManager.get(push.getSessionId());

                    if (proxyChannel != null) {
                        long transferId = TransferChannelManager.getTransferId(transferChannel);
                        ProxyChannelManager.setTransferId(proxyChannel, transferId);
                        proxyChannel.config().setAutoRead(true);

                    }

                    // transfer 发送连接请求
                    ConnectRequest body = new ConnectRequest();
                    body.setSessionId(push.getSessionId());
                    NatMessage connectMsg = new NatMessage(body);
                    transferChannel.writeAndFlush(connectMsg);
                } else {
                    response.setErrMsg("no free transferChannel");
                }
            } else {
                response.setErrMsg("connect fail");
            }

            ctx.channel().writeAndFlush(new NatMessage(response, natMessage.getHeader().getRequestId()));
        }
    }
}
